package com.carmanagement

import grails.transaction.Transactional
import groovy.time.TimeCategory

import java.math.RoundingMode

@Transactional
class StatsService {

	def getStatsForFullTank(Vehicle v) {
		def fullTankList = FullTank.findAllByVehicle(v)
		return prepareFullTankLists(fullTankList)
	}

	def getStatsForMaintenance(Vehicle v) {
		def maintenances = Maintenance.findAllByVehicle(v)
		return prepareMaintenances(maintenances)
	}

	private def prepareActionStats(def actions){
		def costs = []
		def dates = []
		def mileages = []
		def quantities = []
		actions.each {
			costs << it.cost
			dates << it.date
			mileages << it.mileage
		}

		def result = [costsAvg:getAverage(costs), datesAvg:getDateAverage(dates), mileagesAvg:getAverage(mileages)]
		return result
	}

	private def prepareFullTankLists(List fullTankList){
		def result = prepareActionStats( fullTankList )
		def quantities = fullTankList.collectNested { it.quantity}

		result << [quantitiesAvg:getAverage(quantities)]
		return result
	}

	private def prepareMaintenances(def maintenances){
		def result = prepareActionStats( maintenances )
		def nextMaintenance = maintenances.collect{it.predictedDate}.minus(null).min()
		result << [nextMaintenance:nextMaintenance]
		return result
	}

	private def getAverage = {List l ->
		if(l.size() < 1){
			return 0
		}
		BigDecimal result = l.sum() / l.size()
		return result.setScale(2, RoundingMode.UP)
	}

	private def getDateAverage = {List l ->
		if(l.size() <= 1 ){
			return 0
		}
		l.sort()
		use(TimeCategory){
			def durations = []
			def previousDate = null
			l.each{
				if(previousDate){
					def diff =  it - previousDate
					durations << diff.days
				}
				previousDate = it
			}
			BigDecimal result = durations.sum() / durations.size()
			return result.setScale(2, RoundingMode.UP)
		}
	}
}
